#include "app_btn.h"

typedef enum
{
    SINGLE_CLICK = 1 << 0,   // 单击
    DOUBLE_CLICK = 1 << 1,   // 双击
    MULTIPLE_CLICK = 1 << 2, // 连击
    LONG_CLICK = 1 << 3,     // 长按
} app_btn_capacity_t;

typedef struct
{
    click_cb cb; // 回调
} btn_single_click_t;

typedef struct
{
    unsigned int timeout; // 超时
    click_cb cb;          // 回调
} btn_double_click_t;

typedef struct
{
    click_cb cb;            // 回调
    unsigned int timeout;   // 超时
    unsigned char multiple; // 连击次数
} btn_multiple_click_t;

typedef struct
{
    unsigned int timeout; // 超时
    click_cb cb;          // 回调
} btn_long_click_t;

typedef struct
{
    unsigned int first;                  // 第一次时间
    unsigned int last;                   // 最后一个时间
    unsigned char count;                 // 有效次数
    unsigned char release;               // 松手
    drv_btn_state_t effective;           // 有效电平
    app_btn_capacity_t capacity;         // 按键能力
    btn_single_click_t single_click;     // 单击
    btn_double_click_t double_click;     // 双击
    btn_multiple_click_t multiple_click; // 连击
    btn_long_click_t long_click;         // 长按

    unsigned char current_state; // 当前状态
} btn_click_t;

volatile static btn_click_t sg_btn_click[APP_BTN_MAX] = {0x00};

static click_cb sg_factory_btn_cb = NULL;
// @note: 后面新增需求，连击5下 进行光耦校准；单独出来一个结构对象来做
volatile static btn_multiple_click_t sg_other_multiple[APP_BTN_MAX];

app_menu_t sg_menu = {0x00};

void app_btn_effective_set(app_btn_t btn, app_btn_effective_t effective)
{
    ret_if_true(btn >= APP_BTN_MAX)

        if (effective == BTN_EFFECTIVE_HIGH)
    {
        sg_btn_click[btn].effective = BTN_STATE_HIGH;
    }
    else
    {
        sg_btn_click[btn].effective = BTN_STATE_LOW;
    }
    sg_btn_click[btn].capacity = 0x00;
}

void app_btn_single_click_cb_register(app_btn_t btn, click_cb cb)
{
    ret_if_true(btn >= APP_BTN_MAX)

        sg_btn_click[btn]
            .capacity |= SINGLE_CLICK;
    sg_btn_click[btn].single_click.cb = cb;
}

void app_btn_double_click_cb_register(app_btn_t btn, click_cb cb, unsigned int timeout)
{
    ret_if_true(btn >= APP_BTN_MAX)

        sg_btn_click[btn]
            .capacity |= DOUBLE_CLICK;
    sg_btn_click[btn].double_click.cb = cb;
    sg_btn_click[btn].double_click.timeout = timeout;
}

void app_btn_multiple_click_cb_register(app_btn_t btn, click_cb cb, unsigned int timeout, unsigned char multiple)
{
     ret_if_true(btn >= APP_BTN_MAX)

    sg_btn_click[btn].capacity |= MULTIPLE_CLICK;
    sg_btn_click[btn].multiple_click.cb = cb;
    sg_btn_click[btn].multiple_click.timeout = timeout;
    sg_btn_click[btn].multiple_click.multiple = multiple;
}

void app_btn_other_multiple_click_cb_register(app_btn_t btn, click_cb cb, unsigned int timeout, unsigned char multiple)
{
    ret_if_true(btn >= APP_BTN_MAX)

    sg_other_multiple[btn].cb = cb;
    sg_other_multiple[btn].multiple = multiple;
    sg_other_multiple[btn].timeout = timeout;
}

void app_btn_long_click_cb_register(app_btn_t btn, click_cb cb, unsigned int timeout)
{
    ret_if_true(btn >= APP_BTN_MAX)

        sg_btn_click[btn]
            .capacity |= LONG_CLICK;
    sg_btn_click[btn].long_click.cb = cb;
    sg_btn_click[btn].long_click.timeout = timeout;
}

void app_btn_factory_cb_register(click_cb cb)
{
    sg_factory_btn_cb = cb;
}

static void app_btn_irq_handler(drv_btn_type_t type, drv_btn_state_t state)
{
    unsigned char btn = type;

    if (sg_btn_click[btn].effective != state)
    {
        sg_btn_click[btn].release = true;
        return;
    }
    if (sg_btn_click[btn].count == 0)
    {
        sg_btn_click[btn].count = 1;
        sg_btn_click[btn].first = app_sys_ticks;
    }
    else
    {
        sg_btn_click[btn].count += 1;
    }
    sg_btn_click[btn].last = app_sys_ticks;
    sg_btn_click[btn].release = false;

    if (btn == APP_BTN_A)
    {
        if (drv_btn_read_level(BTN_B) == 1) // Clockwise
        {
            app_set_Clockwise();
        }
        else // Counterclockwise
        {
            app_set_Counterclockwise();
        }
    }
}

static void app_btn_release_init(void)
{
    for (unsigned char i = 0; i < APP_BTN_MAX; i++)
    {
        sg_btn_click[i].release = true;
        sg_btn_click[i].count = 0x00;
    }
}

static void app_btn_click_clear(unsigned char index)
{
    sg_btn_click[index].count = 0;
    sg_btn_click[index].first = 0;
    sg_btn_click[index].last = 0;
    sg_btn_click[index].current_state = 0;
}

static void app_btn_double_click_handler_by_index(unsigned char index)
{
    if (time_after(app_sys_ticks, sg_btn_click[index].first + sg_btn_click[index].double_click.timeout))
    {
        if (sg_btn_click[index].count == 2 && sg_btn_click[index].release && sg_btn_click[index].double_click.cb)
        {
            sg_btn_click[index].double_click.cb((app_btn_t)index, APP_DOUBLE_CLICK);
            app_btn_click_clear(index);
        }
    }
}

static void app_btn_double_click_handler(void)
{
    for (unsigned char i = 0; i < APP_BTN_MAX; i++)
    {
        if ((sg_btn_click[i].capacity & DOUBLE_CLICK) == 0)
        {
            continue;
        }

        if (sg_btn_click[i].count > 0)
        {
            app_btn_double_click_handler_by_index(i);
        }
    }
}

static void app_btn_long_click_handler(void)
{
    for (unsigned char i = 0; i < APP_BTN_MAX; i++)
    {
        if ((sg_btn_click[i].capacity & LONG_CLICK) == 0)
        {
            continue;
        }

        if (sg_btn_click[i].count >= 0x01)
        {
            if (time_after(app_sys_ticks, sg_btn_click[i].last + sg_btn_click[i].long_click.timeout))
            {
                sg_btn_click[i].long_click.cb((app_btn_t)i, APP_LONG_CLICK);
                app_btn_click_clear(i);
            }
        }
    }
}

static void app_btn_multiple_click_handler(void)
{
    for (unsigned char i = 0; i < APP_BTN_MAX; i++)
    {
        if ((sg_btn_click[i].capacity & MULTIPLE_CLICK) == 0)
        {
            continue;
        }

        if (time_after(app_sys_ticks, sg_btn_click[i].first + sg_btn_click[i].multiple_click.timeout))
        {
            if (sg_btn_click[i].count == sg_btn_click[i].multiple_click.multiple)
            {
                sg_btn_click[i].multiple_click.cb((app_btn_t)i, APP_MULTIPLE_CLICK);
                app_btn_click_clear(i);
            }
            // else if (sg_btn_click[i].count == sg_other_multiple[i].multiple)
            // {
            //     sg_other_multiple[i].cb((app_btn_t)i, APP_MULTIPLE_CLICK);
            // }
        }
    }
}


static void app_btn_click_release_handler(void)
{
    for (unsigned char i = 0; i < APP_BTN_MAX; i++)
    {
        if (sg_btn_click[i].release != true || sg_btn_click[i].count == 0)
        {
            continue;
        }
        // 已经松手了，不考虑长按；获取双击或者多击 最长超时
        unsigned int timeout = 0;
        if (sg_btn_click[i].double_click.timeout > sg_btn_click[i].multiple_click.timeout)
        {
            timeout = sg_btn_click[i].double_click.timeout;
        }
        else
        {
            timeout = sg_btn_click[i].multiple_click.timeout;
        }
        if (sg_menu.state == MENU_BAT_LOCK_STANDBY || sg_menu.state == MENU_TIP || sg_menu.state == MENU_STANDBY)   timeout = 0;
        if (time_after(app_sys_ticks, sg_btn_click[i].last + timeout))
        {
            if (sg_btn_click[i].single_click.cb)
            {
                sg_btn_click[i].single_click.cb((app_btn_t)i, APP_SINGLE_CLICK);
            }
            app_btn_click_clear(i);
        }
    }
}

void app_btn_init(void)
{
    drv_btn_init();
    app_btn_release_init();
    drv_btn_cb_register(app_btn_irq_handler);
}

void app_btn_task(void)
{
    app_btn_double_click_handler();
    app_btn_multiple_click_handler();
    app_btn_long_click_handler();
    app_btn_click_release_handler();

    app_menu_task();
}

void app_dev_enter_btn_feed_cb_handler(app_btn_t btn, app_btn_state_t state) // 短按
{
    if (sg_menu.state == MENU_FEED) // 菜单喂食：出粮1份
    {
        app_buzzer_start();
        app_set_menu_led(MENU_UNLOCK);
        if (sg_alarm_mgr.bat_off == 1)
            return; // 电量不足
        app_release_set_value(0x01);
    }
    else if (sg_menu.state == MENU_RESET) // 菜单复位：菜单复位
    {
        app_buzzer_start();
        app_set_menu_led(MENU_RESET);
    }
    else if (sg_menu.state == MENU_UNLOCK) // 菜单解锁：菜单解锁
    {
        app_buzzer_start();
        app_set_menu_led(MENU_UNLOCK);
    }
    else if (sg_menu.state == MENU_BAT_LOCK) // 电池上锁：电池上锁
    {
        app_buzzer_start();
        app_set_menu_led(MENU_BAT_LOCK);
    }
    else if (sg_menu.state == MENU_DC_LOCK) // DC上锁：DC上锁
    {
        app_buzzer_start();
        app_set_menu_led(MENU_DC_LOCK);
    }
    else if (sg_menu.state == MENU_BAT_LOCK_STANDBY || sg_menu.state == MENU_TIP || sg_menu.state == MENU_STANDBY) // 待机上锁/提示/待机：电池上锁
    {
        app_led_toggle(APP_LED_WIFI, APP_TOGGLE_FAST_TIME, 0x00);
        app_wifi_set_on();
        app_set_menu_led(MENU_BAT_LOCK);
    }
}

void app_dev_enter_btn_resetwifi_cb_handler(app_btn_t btn, app_btn_state_t state) // 长按
{
    if (sg_menu.state == MENU_RESET) // 菜单复位：复位wifi
    {
        app_buzzer_start();
        app_set_menu_led(MENU_UNLOCK);
        app_plan_clear_to_flash();
        app_clear_time_rec();
        app_uart_tx_wifi_smart_config_reset();
    }
    else if (sg_menu.state == MENU_UNLOCK)
    {
        app_buzzer_start();
        if (dev_obj->type == BAT_TYPE)
        {
            app_set_menu_led(MENU_BAT_LOCK_STANDBY); // 菜单解锁：待机上锁
        }
        else
        {
            app_set_menu_led(MENU_DC_LOCK); // 菜单解锁：DC上锁
        }
    }
    else if (sg_menu.state == MENU_FEED) // 菜单喂食：菜单喂食
    {
        app_buzzer_start();
        if (dev_obj->type == BAT_TYPE)
        {
            app_set_menu_led(MENU_BAT_LOCK_STANDBY); // 菜单解锁：待机上锁
        }
        else
        {
            app_set_menu_led(MENU_DC_LOCK); // 菜单解锁：DC上锁
        }
    }
    else if (sg_menu.state == MENU_DC_LOCK) // DC上锁：菜单解锁
    {
        app_buzzer_start();
        app_set_menu_led(MENU_UNLOCK);
    }
    else if (sg_menu.state == MENU_BAT_LOCK) // 电池上锁：菜单解锁
    {
        app_buzzer_start();
        app_set_menu_led(MENU_UNLOCK);
    }
    else if (sg_menu.state == MENU_BAT_LOCK_STANDBY || sg_menu.state == MENU_TIP || sg_menu.state == MENU_STANDBY) // 待机上锁：电池上锁
    {
        app_led_toggle(APP_LED_WIFI, APP_TOGGLE_FAST_TIME, 0x00);
        app_wifi_set_on();
        app_set_menu_led(MENU_BAT_LOCK);
    }
}

void app_dev_btn_rotate_cb_handler(app_btn_t btn, app_btn_state_t state)
{
    ;
}

/////////////////////////////////////////////////////////////////////////////
void app_menu_Init(void)
{
    app_set_menu_led(MENU_UNLOCK);
}

void app_menu_task(void)
{
    if (sg_menu.state == MENU_UNLOCK || sg_menu.state == MENU_FEED || sg_menu.state == MENU_RESET)
    {
        if (time_after(app_sys_ticks, sg_menu.last + MENU_TIMEOUT))
        {
            if (dev_obj->type == BAT_TYPE)
            {
                app_set_menu_led(MENU_BAT_LOCK_STANDBY);
            }
            else
            {
                app_set_menu_led(MENU_DC_LOCK);
            }
        }
        if (time_after(app_sys_ticks, sg_menu.last + 3000) && sg_alarm_mgr.bat_off == 1)
        {
            app_set_menu_led(MENU_BAT_LOCK_STANDBY);
        }
    }
    else if (sg_menu.state == MENU_DC_LOCK)
    {
        if (dev_obj->type == BAT_TYPE)
        {
            app_set_menu_led(MENU_BAT_LOCK);
        }
    }
    else if (sg_menu.state == MENU_BAT_LOCK)
    {
        if (dev_obj->type == BAT_TYPE)
        {
            if (time_after(app_sys_ticks, sg_menu.last + MENU_TIMEOUT))
            {
                app_set_menu_led(MENU_BAT_LOCK_STANDBY);
            }
            if (time_after(app_sys_ticks, sg_menu.last + 3000) && sg_alarm_mgr.bat_off == 1)
            {
                app_set_menu_led(MENU_BAT_LOCK_STANDBY);
            }
        }
        else
        {
            app_set_menu_led(MENU_DC_LOCK);
        }
    }
    else if (sg_menu.state == MENU_BAT_LOCK_STANDBY)
    {
        if (time_after(app_sys_ticks, sg_menu.last + 5000))
        {
            app_set_menu_led(MENU_TIP);
        }
        if (dev_obj->type == DC_TYPE)
        {
            app_led_toggle(APP_LED_WIFI, APP_TOGGLE_FAST_TIME, 0x00);
            app_wifi_set_on();
            app_set_menu_led(MENU_DC_LOCK);
        }
    }
    else if (sg_menu.state == MENU_TIP)
    {
        if (time_after(app_sys_ticks, sg_menu.last + 1000))
        {
            app_set_menu_led(MENU_STANDBY);
        }
        if (dev_obj->type == DC_TYPE)
        {
            app_led_toggle(APP_LED_WIFI, APP_TOGGLE_FAST_TIME, 0x00);
            app_wifi_set_on();
            app_set_menu_led(MENU_DC_LOCK);
        }
    }
    else if (sg_menu.state == MENU_STANDBY)
    {
        if (dev_obj->type == DC_TYPE)
        {
            app_led_toggle(APP_LED_WIFI, APP_TOGGLE_FAST_TIME, 0x00);
            app_wifi_set_on();
            app_set_menu_led(MENU_DC_LOCK);
        }
    }
}

void app_set_menu_led(app_menu_state_t state) // 状态更新
{
    if (state == MENU_UNLOCK)
    {
        sg_menu.state = MENU_UNLOCK;
        sg_menu.last = app_sys_ticks;
        app_led_on(APP_LED_FEED);
        app_led_on(APP_LED_RESET);
        app_led_on(APP_LED_UNLOCK);
        app_led_off(APP_LED_LOCK);
    }
    else if (state == MENU_FEED)
    {
        sg_menu.state = MENU_FEED;
        sg_menu.last = app_sys_ticks;
        app_led_toggle(APP_LED_FEED, APP_TOGGLE_SLOW_TIME, 0);
        app_led_on(APP_LED_RESET);
        app_led_on(APP_LED_UNLOCK);
        app_led_off(APP_LED_LOCK);
    }
    else if (state == MENU_RESET)
    {
        sg_menu.state = MENU_RESET;
        sg_menu.last = app_sys_ticks;
        app_led_toggle(APP_LED_RESET, APP_TOGGLE_SLOW_TIME, 0);
        app_led_on(APP_LED_FEED);
        app_led_on(APP_LED_UNLOCK);
        app_led_off(APP_LED_LOCK);
    }
    else if (state == MENU_DC_LOCK)
    {
        sg_menu.state = MENU_DC_LOCK;
        app_led_on(APP_LED_FEED);
        app_led_on(APP_LED_RESET);
        app_led_off(APP_LED_UNLOCK);
        app_led_on(APP_LED_LOCK);
    }
    else if (state == MENU_BAT_LOCK)
    {
        sg_menu.state = MENU_BAT_LOCK;
        sg_menu.last = app_sys_ticks;
        app_led_on(APP_LED_FEED);
        app_led_on(APP_LED_RESET);
        app_led_off(APP_LED_UNLOCK);
        app_led_on(APP_LED_LOCK);
    }
    else if (state == MENU_BAT_LOCK_STANDBY)
    {
        if (app_release_is_ok() == 0)
            return;
        sg_menu.state = MENU_BAT_LOCK_STANDBY;
        sg_menu.last = app_sys_ticks;
        app_led_off(APP_LED_FEED);
        app_led_off(APP_LED_RESET);
        app_led_off(APP_LED_UNLOCK);
        app_led_off(APP_LED_LOCK);
        app_led_off(APP_LED_WIFI);
        app_led_off(APP_LED_BAT);
        app_led_off(APP_LED_JAM);
    }
    else if (state == MENU_TIP)
    {
        if (app_release_is_ok() == 0)
            return;
        sg_menu.state = MENU_TIP;
        sg_menu.last = app_sys_ticks;
        app_led_off(APP_LED_FEED);
        app_led_off(APP_LED_RESET);
        app_led_off(APP_LED_UNLOCK);
        app_led_on(APP_LED_LOCK);
        app_led_off(APP_LED_WIFI);
        app_led_off(APP_LED_BAT);
        app_led_off(APP_LED_JAM);
    }
    else if (state == MENU_STANDBY)
    {
        if (app_release_is_ok() == 0)
            return;
        sg_menu.state = MENU_STANDBY;
        app_led_off(APP_LED_FEED);
        app_led_off(APP_LED_RESET);
        app_led_off(APP_LED_UNLOCK);
        app_led_off(APP_LED_LOCK);
        app_led_off(APP_LED_WIFI);
        app_led_off(APP_LED_BAT);
        app_led_off(APP_LED_JAM);
    }
}

void app_set_Clockwise(void) // 顺时针
{
    if (sg_menu.state == MENU_UNLOCK) // 菜单解锁：菜单复位
    {
        app_buzzer_start();
        app_set_menu_led(MENU_RESET);
    }
    else if (sg_menu.state == MENU_FEED) // 菜单喂食：菜单复位
    {
        app_buzzer_start();
        app_set_menu_led(MENU_RESET);
    }
    else if (sg_menu.state == MENU_RESET) // 菜单复位：菜单复位
    {
        app_buzzer_start();
        app_set_menu_led(MENU_RESET);
    }
    else if (sg_menu.state == MENU_DC_LOCK) // DC上锁：DC上锁
    {
        app_buzzer_start();
        app_set_menu_led(MENU_DC_LOCK);
    }
    else if (sg_menu.state == MENU_BAT_LOCK) // 电池上锁：电池上锁
    {
        app_buzzer_start();
        app_set_menu_led(MENU_BAT_LOCK);
    }
    else if (sg_menu.state == MENU_BAT_LOCK_STANDBY || sg_menu.state == MENU_TIP || sg_menu.state == MENU_STANDBY) // 待机上锁/提示/待机：电池上锁
    {
        app_led_toggle(APP_LED_WIFI, APP_TOGGLE_FAST_TIME, 0x00);
        app_wifi_set_on();
        app_set_menu_led(MENU_BAT_LOCK);
    }
}

void app_set_Counterclockwise(void) // 逆时针
{
    if (sg_menu.state == MENU_UNLOCK) // 菜单解锁：菜单喂食
    {
        app_buzzer_start();
        app_set_menu_led(MENU_FEED);
    }
    else if (sg_menu.state == MENU_FEED) // 菜单喂食：菜单喂食
    {
        app_buzzer_start();
        app_set_menu_led(MENU_FEED);
    }
    else if (sg_menu.state == MENU_RESET) // 菜单复位：菜单喂食
    {
        app_buzzer_start();
        app_set_menu_led(MENU_FEED);
    }
    else if (sg_menu.state == MENU_DC_LOCK) // DC上锁：DC上锁
    {
        app_buzzer_start();
        app_set_menu_led(MENU_DC_LOCK);
    }
    else if (sg_menu.state == MENU_BAT_LOCK) // 电池上锁：电池上锁
    {
        app_buzzer_start();
        app_set_menu_led(MENU_BAT_LOCK);
    }
    else if (sg_menu.state == MENU_BAT_LOCK_STANDBY || sg_menu.state == MENU_TIP || sg_menu.state == MENU_STANDBY) // 待机上锁/提示/待机：电池上锁
    {
        app_led_toggle(APP_LED_WIFI, APP_TOGGLE_FAST_TIME, 0x00);
        app_wifi_set_on();
        app_set_menu_led(MENU_BAT_LOCK);
    }
}

unsigned char app_get_menu_state(void)
{
    return sg_menu.state;
}

void app_dev_btn_esc_burn_cb_handler(app_btn_t btn, app_btn_state_t state)
{
    if ((sg_menu.state == MENU_RESET || sg_menu.state == MENU_UNLOCK) && sg_burn_mgr.state == 1)
    {
        sg_burn_mgr.state = 0;
        app_motor_stop();
    }
}

void app_dev_btn_enter_burn_cb_handler(app_btn_t btn, app_btn_state_t state)
{
    if (sg_menu.state == MENU_RESET && sg_burn_mgr.state == 0 && sg_alarm_mgr.bat_off == 0)
    {
        sg_burn_mgr.state = 1;
        app_motor_forward();
    }
}

